import { Logger } from "../log/logger";
import MathUtils from "../utils/MathUtils";
import Utils from "../utils/Utils";
import { SoundItem, SoundOption, soundMusic } from "./SoundItem";

export class SoundTypeItem {

    private _items: SoundItem[] = [];
    private _active: boolean;
    private _type: number;
    private _opt: SoundTypeOption;

    /**玩家自定义音量 */
    private _volume: number = 100;

    /**系统基础音量 */
    private _baseVolume: number = 100;

    /**压制系数，仅仅压制时候使用 */
    private _ratio: number = 100;

    constructor(type: number, opt: SoundTypeOption) {
        this._type = type;
        this._opt = opt;
    }


    play(url: string, param?: SoundOption) {
        let len = this._items.length;
        if (len >= this._opt.maxInstance) {
            if (this._opt.replaceable) {
                this._items.sort((a, b) => a.opt.priority - b.opt.priority);
                this._items.shift().stop();

            } else {
                Logger.logBusiness("max sound limit", "sound");
                return;
            }
        }
        let item = this._type == 0 ? soundMusic.create() : SoundItem.create();
        item.type = this._type;
        this.addItem(item);
        item.complete = Laya.Handler.create(this, this.removeItem, [item]);
        item.play(url, param);
        return item;
    }

    stop(url?: string) {
        let items: SoundItem[] = [];
        for (let elm of this._items) {
            if (this.equal(elm.url, url)) {
                items.push(elm);
            }
        }
        items.forEach(v => v.stop());
    }

    stopAll() {
        this._items.forEach(v => v.stop());
    }

    /**是否被该类型压制*/
    supressdByType(type: number) {
        let opt = this._opt;
        if (!opt) return false;
        let supresses = opt.supresses;
        if (!supresses || !supresses.length) return false;
        return !!supresses.find(supress => supress.type == type);
    }

    updateVolume() {
        for (let elm of this._items) {
            elm.baseValume = this.volume;
        }
    }

    //设置基础音量与用户音量
    setVolume(base: number, use: number) {
        this._baseVolume = base;
        this._volume = use;
        this.updateVolume();
    }

    /**压制结束 */
    ratioStop(slow: boolean = false) {
        this.ratioVolume = 100;
    }

    addItem(item: SoundItem) {
        this._items.push(item);
        this._active = this._items.length > 0;
    }

    removeItem(item: SoundItem) {
        this._items.remove(item);
        this._active = this._items.length > 0;
    }

    equal(url1: string, url2: string) {
        return Laya.URL.getFileName(url1) === Laya.URL.getFileName(url2);
    }

    /**基础音量 */
    public get volume() {
        return Utils.lerpScale(this._baseVolume, 100, this._opt.volume, this._volume, this._ratio);
    }

    /**设置压制系数 */
    public set ratioVolume(v: number) {
        if (v != this._ratio) {
            this._ratio = v;
            this.updateVolume();
        }
    }

    public set volueByUI(v: number) {
        if (v != this._volume) {
            this._volume = v;
            this.updateVolume();
        }
    }

    /**UI显示，用于用户控制 */
    public get volueByUI() {
        return this._volume;
    }

    public get active() {
        return this._active;
    }

    get baseVolume() {
        return this._baseVolume || 100;
    }

    set baseVolume(v: number) {
        this._baseVolume = v;

        this.updateVolume();
    }

    get useVolume() {
        return this._volume;
    }

    set useVolume(v: number) {
        this._volume = v;
    }
}

export interface SoundTypeOption {
    volume?: number;        //音量0~100
    maxInstance?: number;   //最大发声数
    interval?: number;      //播放间隔
    replaceable?: number;   //达到最大发声数时是否可顶替  1可顶替 0 不可顶替

    supresses?: SoundSupressOption[];//压制项列表
}

export interface SoundSupressOption {
    type: number;
    attackTime: number;     //开始压制时长
    ratio: number;          //压制系数
    releaseTime: number;    //释放压制时长
}